package com.price.common.extend

import android.app.Activity
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

inline fun Activity.launch(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.Main,
    crossinline action: suspend () -> Unit,
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            action()
        } catch (e: Exception) {
            doCustomCrashListener?.onCrash(e)
        }
    }
}

inline fun Fragment.launch(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.Main,
    crossinline action: suspend () -> Unit,
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            action()
        } catch (e: Exception) {
            doCustomCrashListener?.onCrash(e)
        }
    }
}

inline fun Context.launch(
    dispatcher: CoroutineDispatcher = Dispatchers.Main,
    crossinline action: suspend () -> Unit,
) {
    GlobalScope.launch(dispatcher) {
        try {
            action()
        }catch (e:Exception){
            doCustomCrashListener?.onCrash(e)
        }
    }
}


inline fun <T> Activity.launch(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> T,
    crossinline callBack: (T) -> Unit
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            val result = action()
            owner.lifecycleScope.launch(Dispatchers.Main) {
                try {
                    callBack(result)
                } catch (e: Exception) {
                    doCustomCrashListener?.onCrash(e)
                }
            }
        } catch (e: Exception) {
            doCustomCrashListener?.onCrash(e)
        }
    }
}


inline fun <T> Fragment.launch(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> T,
    crossinline callBack: (T) -> Unit
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            val result = action()
            owner.lifecycleScope.launch(Dispatchers.Main) {
                try {
                    callBack(result)
                } catch (e: Exception) {
                    doCustomCrashListener?.onCrash(e)
                }
            }
        } catch (e: Exception) {
            doCustomCrashListener?.onCrash(e)
        }
    }
}

inline fun <T> Context.launch(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> T,
    crossinline callBack: (T) -> Unit
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            val result = action()
            owner.lifecycleScope.launch(Dispatchers.Main) {
                try {
                    callBack(result)
                } catch (e: Exception) {
                    doCustomCrashListener?.onCrash(e)
                }
            }
        } catch (e: Exception) {
            doCustomCrashListener?.onCrash(e)
        }
    }
}